//SPDX-FileCopyrightText: Copyright 2022-2024 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

package admin_org_api_serv

import (
	"context"
	"time"

	"atomgit.com/openlinksaas-org/api-server/admin_api_serv/admin_common"
	"atomgit.com/openlinksaas-org/api-server/api_common"
	"atomgit.com/openlinksaas-org/api-server/config"
	"atomgit.com/openlinksaas-org/api-server/dao"
	"atomgit.com/openlinksaas-org/api-server/dao/org_dao"
	"atomgit.com/openlinksaas-org/api-server/dao/user_dao"
	"atomgit.com/openlinksaas-org/proto-gen-go.git/notices/notices_org"
	"atomgit.com/openlinksaas-org/proto-gen-go.git/org_api"
	"go.mongodb.org/mongo-driver/mongo"
)

type OrgAdminApiImpl struct {
	org_api.UnimplementedOrgAdminApiServer
	adminCfg *config.AdminCfg
}

func NewOrgAdminApiImpl(adminCfg *config.AdminCfg) *OrgAdminApiImpl {
	return &OrgAdminApiImpl{adminCfg: adminCfg}
}

func (apiImpl *OrgAdminApiImpl) List(ctx context.Context, req *org_api.AdminListRequest) (*org_api.AdminListResponse, error) {
	emptyList := []*org_api.OrgInfo{}

	sess, ok := dao.CacheDao.GetAdminSession(ctx, req.AdminSessionId)
	if !ok {
		return &org_api.AdminListResponse{
			Code:    org_api.AdminListResponse_CODE_WRONG_SESSION,
			ErrMsg:  "会话不存在",
			OrgList: emptyList,
		}, nil
	}
	if !sess.AuthOk {
		return &org_api.AdminListResponse{
			Code:    org_api.AdminListResponse_CODE_NOT_AUTH,
			ErrMsg:  "未授权会话",
			OrgList: emptyList,
		}, nil
	}
	adminUserCfg, err := admin_common.GetAdminUserConfig(ctx, apiImpl.adminCfg, sess.UserName)
	if err != nil {
		return nil, err
	}
	if !adminUserCfg.PermInfo.OrgPerm.Read {
		return &org_api.AdminListResponse{
			Code:    org_api.AdminListResponse_CODE_NO_PERMISSION,
			ErrMsg:  "没有权限",
			OrgList: emptyList,
		}, nil
	}

	orgIdList := []string{}
	if req.FilterByUserId {
		orgIdList, err = org_dao.MemberDao.DistinctByUser(ctx, req.UserId)
		if err != nil {
			return nil, err
		}
	}

	count, err := org_dao.OrgInfoDao.Count(ctx, req.FilterByKeyword, req.Keyword, req.FilterByUserId, orgIdList)
	if err != nil {
		return nil, err
	}

	orgItemList, err := org_dao.OrgInfoDao.List(ctx, req.FilterByKeyword, req.Keyword, req.FilterByUserId, orgIdList, int64(req.Offset), int64(req.Limit))
	if err != nil {
		return nil, err
	}
	//补充用户信息
	userIdList := []string{}
	for _, orgItem := range orgItemList {
		userIdList = append(userIdList, orgItem.OwnerUserId)
	}
	userItemList, err := user_dao.UserInfoDao.ListById(ctx, userIdList)
	if err != nil {
		return nil, err
	}
	userItemMap := map[string]*user_dao.UserInfoDbItem{}
	for _, userItem := range userItemList {
		userItemMap[userItem.UserId] = userItem
	}
	//生成结果
	orgList := []*org_api.OrgInfo{}
	for _, orgItem := range orgItemList {
		org := orgItem.ToOrgInfo()
		userItem, ok := userItemMap[orgItem.OwnerUserId]
		if ok {
			org.OwnerDisplayName = userItem.BasicInfo.DisplayName
			org.OwnerLogoUri = userItem.BasicInfo.LogoUri
		}
		orgList = append(orgList, org)
	}

	return &org_api.AdminListResponse{
		Code:       org_api.AdminListResponse_CODE_OK,
		TotalCount: count,
		OrgList:    orgList,
	}, nil
}

func (apiImpl *OrgAdminApiImpl) Get(ctx context.Context, req *org_api.AdminGetRequest) (*org_api.AdminGetResponse, error) {
	emptyInfo := &org_api.OrgInfo{
		BasicInfo: &org_api.BasicOrgInfo{},
		Setting:   &org_api.Setting{},
	}

	sess, ok := dao.CacheDao.GetAdminSession(ctx, req.AdminSessionId)
	if !ok {
		return &org_api.AdminGetResponse{
			Code:    org_api.AdminGetResponse_CODE_WRONG_SESSION,
			ErrMsg:  "会话不存在",
			OrgInfo: emptyInfo,
		}, nil
	}
	if !sess.AuthOk {
		return &org_api.AdminGetResponse{
			Code:    org_api.AdminGetResponse_CODE_NOT_AUTH,
			ErrMsg:  "未授权会话",
			OrgInfo: emptyInfo,
		}, nil
	}
	adminUserCfg, err := admin_common.GetAdminUserConfig(ctx, apiImpl.adminCfg, sess.UserName)
	if err != nil {
		return nil, err
	}
	if !adminUserCfg.PermInfo.OrgPerm.Read {
		return &org_api.AdminGetResponse{
			Code:    org_api.AdminGetResponse_CODE_NO_PERMISSION,
			ErrMsg:  "没有权限",
			OrgInfo: emptyInfo,
		}, nil
	}

	orgItem, err := org_dao.OrgInfoDao.Get(ctx, req.OrgId)
	if err != nil {
		return &org_api.AdminGetResponse{
			Code:    org_api.AdminGetResponse_CODE_NO_ORG,
			ErrMsg:  "组织不存在",
			OrgInfo: emptyInfo,
		}, nil
	}

	userItemList, err := user_dao.UserInfoDao.ListById(ctx, []string{orgItem.OwnerUserId})
	if err != nil {
		return nil, err
	}

	org := orgItem.ToOrgInfo()
	if len(userItemList) > 0 {
		org.OwnerDisplayName = userItemList[0].BasicInfo.DisplayName
		org.OwnerLogoUri = userItemList[0].BasicInfo.LogoUri
	}

	return &org_api.AdminGetResponse{
		Code:    org_api.AdminGetResponse_CODE_OK,
		OrgInfo: org,
	}, nil
}

func (apiImpl *OrgAdminApiImpl) Update(ctx context.Context, req *org_api.AdminUpdateRequest) (*org_api.AdminUpdateResponse, error) {
	sess, ok := dao.CacheDao.GetAdminSession(ctx, req.AdminSessionId)
	if !ok {
		return &org_api.AdminUpdateResponse{
			Code:   org_api.AdminUpdateResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	if !sess.AuthOk {
		return &org_api.AdminUpdateResponse{
			Code:   org_api.AdminUpdateResponse_CODE_NOT_AUTH,
			ErrMsg: "未授权会话",
		}, nil
	}
	adminUserCfg, err := admin_common.GetAdminUserConfig(ctx, apiImpl.adminCfg, sess.UserName)
	if err != nil {
		return nil, err
	}
	if !adminUserCfg.PermInfo.OrgPerm.Update {
		return &org_api.AdminUpdateResponse{
			Code:   org_api.AdminUpdateResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	exist, err := org_dao.OrgInfoDao.Exist(ctx, req.OrgId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &org_api.AdminUpdateResponse{
			Code:   org_api.AdminUpdateResponse_CODE_NO_ORG,
			ErrMsg: "组织不存在",
		}, nil
	}

	nowTime := time.Now().UnixNano() / 1e6

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = org_dao.OrgInfoDao.Update(sessCtx, req.OrgId, &org_dao.BasicOrgInfoDbItem{
			OrgName: req.BasicInfo.OrgName,
			OrgDesc: req.BasicInfo.OrgDesc,
		}, nowTime)
		if err != nil {
			return nil, err
		}
		return &org_api.AdminUpdateResponse{
			Code: org_api.AdminUpdateResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	//发送通知
	go api_common.SendNoticeToOrgScope(context.Background(), req.OrgId, &notices_org.UpdateOrgNotice{
		OrgId: req.OrgId,
	})
	return ret.(*org_api.AdminUpdateResponse), nil
}
